﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using Argotic.Syndication;

namespace gmeow.Core
{
    public    class FeedWatcher
    {
        private bool _notStopped;
        public event NewContent NewContentHandler;
        private Dictionary<string, FeedRecord> _feeds= new Dictionary<string, FeedRecord>();
        public bool IsRunning { get { return _notStopped;}}
        private Thread worker;


        public int CycleTimeout { get; set; }

        public void AddFeed(string uniquename, string url, string user, string password)
        {
            FeedRecord r = new FeedRecord();
            r.FeedUri = new Uri(url);
            r.Credentials = new NetworkCredential(user, password);
            _feeds.Add(uniquename, r);

        }
        public void AddFeed(string uniquename, string url)
        {
            AddFeed(uniquename, url, null, null);
        }

        public void Start(int interval)
        {
            if (IsRunning) return;
            _notStopped = true;
            CycleTimeout = interval;
            worker = new Thread(doWork);
            worker.Start();
        }
        public void Stop()
        {
            _notStopped = false;
        }

        private void doWork()
        {
           
            while(_notStopped)
            {
                foreach (var currentFeedRecord in _feeds)
                {
                    //load a feed synchronously
                    //check last change for each entry, add entries that are new
                    //if list is nonempty, create a new content event with respective content.
                    List<String> newTitles = new List<string>();
                    List<String> newDescriptions = new List<string>();
                    DateTime maxTimeStamp  = currentFeedRecord.Value.MostRecentEntryTimeStamp;

                    //lets read the feed
                    AtomFeed atomFeed = AtomFeed.Create(currentFeedRecord.Value.FeedUri, currentFeedRecord.Value.Credentials, null);
                    foreach (var atomEntry in atomFeed.Entries)
                    {
                        if (atomEntry.UpdatedOn > currentFeedRecord.Value.MostRecentEntryTimeStamp)
                        {
                            //keep a max value from all of the new entries in the feed. this will be the sentinel value
                            //to indicate that a new batch has been updated.
                            if(atomEntry.UpdatedOn > maxTimeStamp)
                                maxTimeStamp = atomEntry.UpdatedOn;
                            
                            newTitles.Add(atomEntry.Title.Content);
                            newDescriptions.Add(atomEntry.Summary.Content);
                        }
                    }
                    if (newTitles.Count == 0)
                        continue;

                    currentFeedRecord.Value.MostRecentEntryTimeStamp = maxTimeStamp;

                    NewContentArgs args = GetArgs(atomFeed.Title.Content, newTitles, newDescriptions);

                    if(NewContentHandler !=null)
                        NewContentHandler(this, args);

                }
                Thread.Sleep(CycleTimeout*1000);
            }

        }

        private NewContentArgs GetArgs(string feedname, List<string> newTitles, List<string> newDescriptions)
        {
            NewContentArgs args= new NewContentArgs();
            args.FeedName = feedname;
            args.EntriesDescriptions = newDescriptions.ToArray();
            args.EntriesTitles = newTitles.ToArray();
            return args;
        }


        public void Clear()
        {
            _feeds.Clear();
        }
    }

    internal class FeedRecord
    {
        public Uri FeedUri;
        public ICredentials Credentials;
        public DateTime MostRecentEntryTimeStamp;
    }
}
